using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace _3D
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        public static Point TamanhoTela = new Point(800, 600);
        Camera camera;
        Telhado t;
        VertexPositionTexture[] vertsPlano;
        List<GameObject3D> boxes;
        List<BaseWall> casa;
        VertexBuffer vertexBuffer;
        BasicEffect effect;
        Texture2D grama, parede, topomoinho;
        Moinho moinho1, moinho2;
        BaseWall wall, wall2, wall3, walld1, walld2, walld3, walld4;
        TreeManager Forest;
        Effect currentEffect;
        Vector3 size = new Vector3(4, 4, 4);
        Model3D spaceShip;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            camera = new Camera();
            casa = new List<BaseWall>();
            boxes = new List<GameObject3D>();
        }

        protected override void Initialize()
        {
            graphics.PreferredBackBufferWidth = TamanhoTela.X;
            graphics.PreferredBackBufferHeight = TamanhoTela.Y;
            graphics.ApplyChanges();

            GraphicsDevice.RasterizerState = RasterizerState.CullNone;

            vertsPlano = new VertexPositionTexture[4];
            vertsPlano[0] = new VertexPositionTexture(new Vector3(500, -2, 500), new Vector2(0,0));
            vertsPlano[1] = new VertexPositionTexture(new Vector3(-500, -2, 500), new Vector2(500, 0));
            vertsPlano[2] = new VertexPositionTexture(new Vector3(500, -2, -500), new Vector2(0,500));
            vertsPlano[3] = new VertexPositionTexture(new Vector3(-500, -2, -500), new Vector2(500, 500));

            vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionTexture), vertsPlano.Length, BufferUsage.None);
            vertexBuffer.SetData<VertexPositionTexture>(vertsPlano);

            effect = new BasicEffect(GraphicsDevice);

            base.Initialize();
            
        }

        protected override void LoadContent()
        {
            spaceShip = new Model3D(Content.Load<Model>("spaceship"), new Vector3(50, 4, 60));
            currentEffect = Content.Load<Effect>("Effect");
            spriteBatch = new SpriteBatch(GraphicsDevice);
            grama = Content.Load<Texture2D>("grama");
            parede = Content.Load<Texture2D>("Texture1");
            topomoinho = Content.Load<Texture2D>("topomoinho");
            moinho1 = new Moinho(new Vector3(50, 0, -30), GraphicsDevice, new Vector2(5, 2), camera, parede, topomoinho, grama, 0);
            moinho2 = new Moinho(new Vector3(50, 0, 40), GraphicsDevice, new Vector2(5, 2), camera, parede, topomoinho, grama, 180);
            t = new Telhado(25, GraphicsDevice, camera, new Vector3(15,7,12), parede);

            wall = new BaseWall(new Vector3(0, 0, 0), GraphicsDevice, camera, 1, 4, 14,1);
            wall2 = new BaseWall(new Vector3(0, 0, 28), GraphicsDevice, camera, 0, 4, 18,1);
            wall3 = new BaseWall(new Vector3(0, 0, -2), GraphicsDevice, camera, 0, 4, 18, 1);

            walld1 = new BaseWall(new Vector3(0, 0, 10), GraphicsDevice, camera, 0, 4, 14, 1);
            walld2 = new BaseWall(new Vector3(34, 0, 20), GraphicsDevice, camera, 1, 4, 4, 1);
            walld3 = new BaseWall(new Vector3(20, 0, 4), GraphicsDevice, camera, 1, 4, 10, 1);
            walld4 = new BaseWall(new Vector3(34, 0, 0), GraphicsDevice, camera, 1, 4, 4, 1);

            casa.Add(wall);
            casa.Add(wall2);
            casa.Add(wall3);
            casa.Add(walld1);
            casa.Add(walld2);
            casa.Add(walld3);
            casa.Add(walld4);

            Forest = new TreeManager(camera, GraphicsDevice, 2, Content.Load<Texture2D>("tree"), 20, 15, new Vector3(150, 0, 10));

            for (int i = 0; i < casa.Count; i++)
            {
                for (int j = 0; j < casa[i].wall.Count; j++)
                {
                    boxes.Add(casa[i].wall[j]);
                }
            }
        }
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            spaceShip.Update(camera);
            //camera.Update(boxes);
            camera.LookAt(spaceShip);
            moinho1.Update(camera);
            moinho2.Update(camera);

            foreach (BaseWall b in casa)
                b.Update(camera);

            t.Update(camera);

            foreach (GameObject3D ob in boxes)
                ob.Update(camera);

            Forest.Update(camera);
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            effect.World = camera.world;
            effect.View = camera.view;
            effect.Projection = camera.projection;
            effect.Texture = grama;
            effect.TextureEnabled = true;
            moinho1.Draw(GraphicsDevice);
            moinho2.Draw(GraphicsDevice);
            spaceShip.Draw3D(GraphicsDevice, camera);
            

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
               pass.Apply();

                GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, vertsPlano, 0, 2);
            }
            foreach (BaseWall b in casa)
                b.Draw(GraphicsDevice);

            t.Draw(GraphicsDevice);
            Forest.Draw(GraphicsDevice);
            base.Draw(gameTime);
        }
    }
}
